<template>
  <div class="excel-compare-container">
    <!-- 全屏动画遮罩层，现在用于对比和下载过程 -->
    <transition name="fade">
      <div class="fullscreen-loader" v-if="showCompareAnimation || showDownloadAnimation">
        <div class="compare-animation">
          <div class="compare-spinner"></div>
          <h2 class="compare-text">{{ animationTitle }}</h2>
          <div class="compare-stage">{{ animationStage }}</div>
          <div class="progress-container">
            <div class="progress-bar" :style="{ width: animationProgress + '%' }"></div>
          </div>
          <div class="progress-text">{{ animationProgress }}% 完成</div>
        </div>
      </div>
    </transition>

    <div class="excel-compare">
      <div class="card">
        <div class="card-header">
          <h2>Excel对比工具</h2>
        </div>

        <div class="upload-section">
          <div class="file-uploads">
            <div class="file-upload-container">
              <h3>Excel文件 1</h3>
              <div
                class="file-upload"
                @drop.prevent="handleDrop($event, 1)"
                @dragover.prevent="handleDragOver"
                @dragleave.prevent="handleDragLeave"
              >
                <input
                  type="file"
                  id="file1"
                  accept=".xlsx,.xls"
                  @change="(e) => handleFileChange(e, 1)"
                  class="file-input"
                />
                <label for="file1" class="upload-button">选择Excel文件</label>
                <div class="drag-tip">或将文件拖到此处</div>
                <div class="file-name" v-if="file1">已选择: {{ file1.name }}</div>
                <div class="loading-spinner" v-if="isLoadingExcel1">
                  <div class="spinner"></div>
                  <div class="loading-text">正在加载Excel数据...</div>
                </div>
              </div>
            </div>

            <div class="file-upload-container">
              <h3>Excel文件 2</h3>
              <div
                class="file-upload"
                @drop.prevent="handleDrop($event, 2)"
                @dragover.prevent="handleDragOver"
                @dragleave.prevent="handleDragLeave"
              >
                <input
                  type="file"
                  id="file2"
                  accept=".xlsx,.xls"
                  @change="(e) => handleFileChange(e, 2)"
                  class="file-input"
                />
                <label for="file2" class="upload-button">选择Excel文件</label>
                <div class="drag-tip">或将文件拖到此处</div>
                <div class="file-name" v-if="file2">已选择: {{ file2.name }}</div>
                <div class="loading-spinner" v-if="isLoadingExcel2">
                  <div class="spinner"></div>
                  <div class="loading-text">正在加载Excel数据...</div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- Excel1 数据预览区域 -->
        <div class="preview-section" v-if="excel1Preview.length > 0">
          <h3>Excel 1 数据预览（前5行）</h3>
          <div class="table-wrapper">
            <table class="preview-table">
              <thead>
                <tr>
                  <th v-for="(header, index) in excel1Headers" :key="index">
                    {{ header }}
                  </th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(row, rowIndex) in excel1Preview.slice(1, 6)" :key="rowIndex">
                  <td v-for="(cell, cellIndex) in row" :key="cellIndex">
                    {{ cell }}
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>

        <!-- 排序配置 -->
        <div class="sort-section" v-if="excel1Headers.length > 0">
          <h3>
            排序配置
            <span class="sort-info" v-if="compareMode === 'key'">
              (这些字段将作为对比的唯一标识)
            </span>
          </h3>
          <div class="sort-header">
            <div class="sort-header-left">
              <span class="header-text">列</span>
            </div>
            <div class="sort-header-center">
              <span class="header-text">排序依据</span>
            </div>
            <div class="sort-header-right">
              <span class="header-text">次序</span>
            </div>
          </div>

          <div class="sort-configs">
            <div class="sort-item" v-for="(config, index) in sortConfigs" :key="index">
              <div class="sort-item-left">
                <select
                  v-model="config.field"
                  class="select-input"
                  @change="
                    updateSortConfig(index, 'field', ($event.target as HTMLSelectElement).value)
                  "
                >
                  <option v-for="header in excel1Headers" :key="header" :value="header">
                    {{ header }}
                  </option>
                </select>
              </div>
              <div class="sort-item-center">
                <select
                  v-model="config.type"
                  class="select-input"
                  @change="
                    updateSortConfig(index, 'type', ($event.target as HTMLSelectElement).value)
                  "
                >
                  <option value="string">文本</option>
                  <option value="number">数值</option>
                </select>
              </div>
              <div class="sort-item-right">
                <select
                  v-model="config.order"
                  class="select-input"
                  @change="
                    updateSortConfig(index, 'order', ($event.target as HTMLSelectElement).value)
                  "
                >
                  <option value="asc">升序</option>
                  <option value="desc">降序</option>
                </select>
              </div>
              <div class="sort-item-actions">
                <button class="icon-btn" @click="addSortConfig" title="添加条件">
                  <span class="icon">+</span>
                </button>
                <button
                  class="icon-btn"
                  @click="removeSortConfig(index)"
                  title="删除条件"
                  :disabled="sortConfigs.length <= 1"
                >
                  <span class="icon">-</span>
                </button>
                <button class="icon-btn" @click="copySortConfig(index)" title="复制条件">
                  <span class="icon">&#x2398;</span>
                </button>
              </div>
            </div>
          </div>
        </div>

        <!-- 添加开始对比按钮到字段配置表格上方 -->
        <div class="action-section" v-if="file1 && file2">
          <button
            class="compare-btn"
            @click="compareExcel"
            :disabled="!file1 || !file2 || isComparing || isLoadingExcel1 || isLoadingExcel2"
          >
            {{ isComparing ? '对比中...' : '开始对比' }}
          </button>
        </div>

        <!-- 移动对比方式配置到此处 -->
        <div class="config-section" v-if="excel1Headers.length > 0">
          <div class="config-item">
            <label class="config-label">对比方式：</label>
            <select v-model="compareMode" class="select-input">
              <option value="key">按排序字段对比</option>
              <option value="position">按位置对比</option>
            </select>
          </div>

          <div class="config-item" v-if="compareMode === 'key' && sortConfigs.length === 0">
            <span class="warning-text">请至少添加一个排序字段作为对比依据</span>
          </div>

          <div class="config-item">
            <label class="checkbox-wrapper">
              <input type="checkbox" v-model="ignoreCase" />
              <span>忽略大小写</span>
            </label>
          </div>

          <div class="config-item">
            <label class="checkbox-wrapper">
              <input type="checkbox" v-model="ignoreSpaces" />
              <span>忽略空格</span>
            </label>
          </div>
        </div>

        <!-- 字段配置表格 -->
        <div class="columns-config-section" v-if="columnConfigs.length > 0">
          <h3>字段配置表格</h3>
          <div class="table-wrapper">
            <table class="config-table">
              <thead>
                <tr>
                  <th>字段名称</th>
                  <th class="checkbox-cell">
                    <div class="th-content">
                      <span class="th-label">是否对比</span>
                      <div class="select-all-controls">
                        <button class="mini-btn select-all" @click="selectAllColumns">全选</button>
                        <button class="mini-btn deselect-all" @click="deselectAllColumns">
                          全不选
                        </button>
                      </div>
                    </div>
                  </th>
                  <th>是否为数字</th>
                  <th>忽略小数位</th>
                  <th>对比结果</th>
                  <th>示例</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(config, index) in columnConfigs" :key="index">
                  <td>{{ config.name }}</td>
                  <td class="checkbox-cell">
                    <label class="checkbox-wrapper">
                      <input
                        type="checkbox"
                        :checked="config.shouldCompare"
                        @change="
                          (e) =>
                            updateColumnConfig(
                              index,
                              'shouldCompare',
                              (e.target as HTMLInputElement).checked,
                            )
                        "
                      />
                    </label>
                  </td>
                  <td>
                    <label class="checkbox-wrapper">
                      <input
                        type="checkbox"
                        :checked="config.isNumeric"
                        @change="
                          (e) =>
                            updateColumnConfig(
                              index,
                              'isNumeric',
                              (e.target as HTMLInputElement).checked,
                            )
                        "
                      />
                    </label>
                  </td>
                  <td>
                    <input
                      type="number"
                      class="digit-input"
                      min="0"
                      max="10"
                      :value="config.ignoreDigits"
                      @change="
                        (e) =>
                          updateColumnConfig(
                            index,
                            'ignoreDigits',
                            parseInt((e.target as HTMLInputElement).value) || 0,
                          )
                      "
                      :disabled="!config.isNumeric"
                    />
                  </td>
                  <td
                    :class="{
                      'status-identical': config.comparisonResult === 'identical',
                      'status-different': config.comparisonResult === 'different',
                      'status-not-exist': config.comparisonResult === 'not-exist',
                    }"
                  >
                    {{ getColumnComparisonStatusText(config.comparisonResult) }}
                  </td>
                  <td>
                    <div v-if="config.examples.length > 0" class="examples-wrapper">
                      <div
                        class="example-item"
                        v-for="(example, exIndex) in config.examples"
                        :key="exIndex"
                      >
                        <div class="example-row">
                          <span class="row-label">行号:</span>
                          <span class="row-value"
                            >Excel1:
                            <span class="row-number">{{
                              example.rowNum1 !== undefined ? example.rowNum1 + 1 : '未知'
                            }}</span></span
                          >
                          <span class="row-value"
                            >Excel2:
                            <span class="row-number">{{
                              example.rowNum2 !== undefined ? example.rowNum2 + 1 : '未知'
                            }}</span></span
                          >
                        </div>
                        <div class="example-content">
                          Excel1: <span class="value">{{ example.excel1 }}</span> Excel2:
                          <span class="value">{{ example.excel2 }}</span>
                        </div>
                      </div>
                    </div>
                    <span v-else>-</span>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>

        <!-- 对比结果 -->
        <div class="result-section" v-if="comparisonResult">
          <h3>对比结果</h3>

          <div class="result-summary">
            <div class="summary-item">
              <span class="label">总行数：</span>
              <span class="value">{{ comparisonResult.totalRows }}</span>
            </div>
            <div class="summary-item">
              <span class="label">相同行数：</span>
              <span class="value">{{ comparisonResult.matchedRows }}</span>
            </div>
            <div class="summary-item">
              <span class="label">不同行数：</span>
              <span class="value">{{ comparisonResult.differentRows }}</span>
            </div>
            <div class="summary-item">
              <span class="label">文件1独有：</span>
              <span class="value">{{ comparisonResult.onlyInFile1 }}</span>
            </div>
            <div class="summary-item">
              <span class="label">文件2独有：</span>
              <span class="value">{{ comparisonResult.onlyInFile2 }}</span>
            </div>
          </div>

          <div class="result-actions">
            <button class="download-btn" @click="handleDownloadResults">下载对比结果(Excel)</button>
            <button class="download-btn txt-btn" @click="handleDownloadResultsAsCsv">
              下载对比结果(CSV)
            </button>
          </div>

          <!-- 差异预览 -->
          <div class="diff-preview" v-if="comparisonResult.differences.length > 0">
            <h4>差异预览（显示前10条）</h4>
            <div class="table-wrapper">
              <table class="diff-table">
                <thead>
                  <tr>
                    <th>行号</th>
                    <th>类型</th>
                    <th>文件1内容</th>
                    <th>文件2内容</th>
                  </tr>
                </thead>
                <tbody>
                  <tr
                    v-for="(diff, index) in comparisonResult.differences.slice(0, 10)"
                    :key="index"
                    :class="diff.type"
                  >
                    <td>{{ diff.row }}</td>
                    <td>{{ getDiffTypeText(diff.type) }}</td>
                    <td>{{ diff.content1 || '-' }}</td>
                    <td>{{ diff.content2 || '-' }}</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { useExcelData } from '@/composables/useExcelData'
import { useExcelExport } from '@/composables/useExcelExport'

// 使用 composables
const {
  excel1DataFrame,
  excel2DataFrame,
  excel1Headers,
  excel2Headers,
  excel1Preview,
  excel1Data,
  excel2Data,
  columnConfigs,
  sortConfigs,
  isLoadingExcel1,
  isLoadingExcel2,
  ignoreCase,
  ignoreSpaces,
  compareMode,
  readExcelFile,
  sortDataFrame,
  compareDataFrames,
  analyzeColumnDifferences,
  addSortConfig,
  removeSortConfig,
  copySortConfig,
  updateSortConfig,
  updateColumnConfig,
  selectAllColumns,
  deselectAllColumns,
  clearComparisonResults,
} = useExcelData()

const {
  showDownloadAnimation,
  downloadProgress,
  downloadStage,
  prepareExportData,
  downloadResults,
  downloadResultsAsCsv,
  getDiffTypeText,
} = useExcelExport()

// 文件和对比状态
const file1 = ref<File | null>(null)
const file2 = ref<File | null>(null)
const isComparing = ref(false)
const showCompareAnimation = ref(false)
const compareProgress = ref(0)
const compareStage = ref('准备中...')

// 对比结果
const comparisonResult = ref<any>(null)

// 计算属性用于动画内容
const animationTitle = computed(() => {
  return showCompareAnimation.value ? '正在对比Excel数据' : '正在导出差异结果'
})

const animationStage = computed(() => {
  return showCompareAnimation.value ? compareStage.value : downloadStage.value
})

const animationProgress = computed(() => {
  return showCompareAnimation.value ? compareProgress.value : downloadProgress.value
})

// 处理文件选择
const handleFileChange = async (event: Event, fileNum: number) => {
  const input = event.target as HTMLInputElement
  const file = input.files?.[0]
  if (!file) return

  if (
    !file.name.endsWith('.xlsx') &&
    !file.name.endsWith('.xls') &&
    !file.type.includes('excel') &&
    !file.type.includes('spreadsheet')
  ) {
    ElMessage.error('请选择Excel文件(.xlsx或.xls)')
    input.value = ''
    return
  }

  if (fileNum === 1) {
    file1.value = file
  } else {
    file2.value = file
  }

  await readExcelFile(file, fileNum)
}

// 处理拖拽
const handleDragOver = (event: DragEvent) => {
  event.target && (event.target as HTMLElement).closest('.file-upload')?.classList.add('dragover')
}

const handleDragLeave = (event: DragEvent) => {
  event.target &&
    (event.target as HTMLElement).closest('.file-upload')?.classList.remove('dragover')
}

const handleDrop = async (event: DragEvent, fileNum: number) => {
  event.target &&
    (event.target as HTMLElement).closest('.file-upload')?.classList.remove('dragover')
  const file = event.dataTransfer?.files[0]
  if (!file) return

  if (
    !file.name.endsWith('.xlsx') &&
    !file.name.endsWith('.xls') &&
    !file.type.includes('excel') &&
    !file.type.includes('spreadsheet')
  ) {
    ElMessage.error('请选择Excel文件(.xlsx或.xls)')
    return
  }

  // 创建一个新的 FileList 对象
  const dataTransfer = new DataTransfer()
  dataTransfer.items.add(file)

  // 更新 input 的文件
  const fileInput = document.getElementById(`file${fileNum}`) as HTMLInputElement
  if (fileInput) {
    fileInput.files = dataTransfer.files
    if (fileNum === 1) {
      file1.value = file
    } else {
      file2.value = file
    }
    await readExcelFile(file, fileNum)
  }
}

// 获取列对比结果状态文本
const getColumnComparisonStatusText = (status: string): string => {
  switch (status) {
    case 'identical':
      return '完全一致'
    case 'not-exist':
      return 'Excel2中不存在该列'
    case 'different':
      return '存在不一致'
    default:
      return '未对比'
  }
}

// 对比Excel文件
const compareExcel = async () => {
  if (!file1.value || !file2.value) {
    ElMessage.warning('请选择两个Excel文件进行对比')
    return
  }

  if (!excel1DataFrame.value || !excel2DataFrame.value) {
    ElMessage.warning('Excel文件尚未加载完成，请稍候')
    return
  }

  isComparing.value = true
  compareProgress.value = 0
  compareStage.value = '准备中...'
  showCompareAnimation.value = true

  try {
    // 清空之前的对比结果
    clearComparisonResults()

    compareStage.value = '正在处理第一个Excel文件...'
    compareProgress.value = 5
    let df1 = excel1DataFrame.value
    let data1 = excel1Data.value

    compareStage.value = '正在处理第二个Excel文件...'
    compareProgress.value = 10
    let df2 = excel2DataFrame.value
    let data2 = excel2Data.value

    // 如果是按位置对比且配置了排序字段，则对数据进行排序
    if (compareMode.value === 'position' && sortConfigs.value.length > 0) {
      compareStage.value = '正在对数据进行排序...'
      compareProgress.value = 15

      const sortedDataObj1 = sortDataFrame(df1)
      const sortedDataObj2 = sortDataFrame(df2)

      // 获取排序后的数据
      data1 = sortedDataObj1.data || sortedDataObj1
      data2 = sortedDataObj2.data || sortedDataObj2

      console.log('排序后的data1:', data1)
      console.log('排序后的data2:', data2)
    }

    // 创建进度回调函数
    const progressCallback = (progress: number, stage: string) => {
      compareProgress.value = Math.max(compareProgress.value, progress)
      compareStage.value = stage
    }

    compareStage.value = '正在执行数据对比...'
    compareProgress.value = 20

    // 使用新的异步API和进度回调
    const result = await compareDataFrames(df1, df2, data1, data2, progressCallback)

    compareStage.value = '正在分析列数据差异...'
    compareProgress.value = 95
    analyzeColumnDifferences(data1, data2)

    compareStage.value = '正在生成对比结果...'
    compareProgress.value = 97
    comparisonResult.value = result

    compareStage.value = '准备导出数据...'
    compareProgress.value = 98

    // 预先准备导出数据
    await prepareExportData(result, excel1Data.value, excel2Headers.value, sortConfigs.value)

    compareProgress.value = 100
    compareStage.value = '对比完成！'

    await new Promise((resolve) => setTimeout(resolve, 500))
    showCompareAnimation.value = false

    ElMessage.success(`对比完成！共处理 ${result.totalRows} 行数据`)
  } catch (error) {
    console.error('对比失败:', error)
    ElMessage.error(error instanceof Error ? error.message : '对比失败，请重试')
  } finally {
    isComparing.value = false
    showCompareAnimation.value = false
  }
}

// 处理下载Excel结果
const handleDownloadResults = async () => {
  await downloadResults(
    comparisonResult.value,
    excel1Data.value,
    excel2Data.value,
    columnConfigs.value,
    sortConfigs.value,
    compareMode.value,
  )
}

// 处理下载CSV结果
const handleDownloadResultsAsCsv = async () => {
  await downloadResultsAsCsv(
    comparisonResult.value,
    excel1Data.value,
    columnConfigs.value,
    sortConfigs.value,
  )
}
</script>

<style scoped src="@/styles/excel-compare.css"></style>
